package com.acme.bankapp.domain.bank;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.acme.bankapp.domain.account.Account;
import com.acme.bankapp.domain.account.CheckingAccount;
import com.acme.bankapp.domain.account.SavingAccount;
import com.acme.bankapp.service.bank.ClientRegistrationListener;
import com.acme.bankapp.service.bank.EmailService;
import com.acme.exceptions.ClientDuplicateException;
import com.acme.exceptions.ClientNotExistException;


public class Bank {
	
	private List<Client> clients = new ArrayList<Client>();	
	private List<ClientRegistrationListener> listeners = new ArrayList<ClientRegistrationListener>();
	private ClientRegistrationListener debugListener = new DebugListener();
	private EmailNotificationListener emailListener = new EmailNotificationListener();
	public final static String regLine = "^accounttype=([cs]);balance=([-+]?[0-9]*\\.?[0-9]*);overdraft=([-+]?[0-9]*\\.?[0-9]*);name=(\\w+);gender=([fm]);$";

	public Bank() {
		listeners.add(new ClientRegistrationListener() {
			
			@Override
			public void onClientAdded(Client c) {
				System.out.println("Client: " + c.getClientSalutation() + ", welcomoe!");
			}
		});
		
		listeners.add(emailListener);
		listeners.add(debugListener);
	}
	
	public class DebugListener implements ClientRegistrationListener{

		@Override
		public void onClientAdded(Client client) {
			System.out.println("Client " + client.getClientSalutation() +" added on " + new java.util.Date());
		}
		
	}
	
	public class EmailNotificationListener implements ClientRegistrationListener{

		@Override
		public void onClientAdded(Client client) {
			Email email = new EmailImpl("Your bank", client.getEmailAddress(), "Salut!", "Welcome on board, Client!");
			EmailService.getEmailService().addEmail(email);			
		}	
		
	}
	
	public void addClient(Client client) throws ClientDuplicateException, ClientNotExistException {
		for (int i = 0; i < this.getClientCount(); i++) {
			if(client.getName().equals(this.getClientById(i).getName())) {
				throw new ClientDuplicateException("Client already exist!");
			}
		}
		clients.add(client);
		for(ClientRegistrationListener l : this.listeners) {
			l.onClientAdded(client);
		}
	}
	
	public void addClient(String str) throws ClientDuplicateException, ClientNotExistException {
		Pattern pattern = Pattern.compile(regLine);
		Matcher matcher = pattern.matcher(str);
		Account account;
		Gender gender;
		while(matcher.find()) {
			if (matcher.group(1).equals("c")) {
				account = new CheckingAccount(Double.parseDouble(matcher.group(2)),Double.parseDouble(matcher.group(3)));
			} else {
				account = new SavingAccount(Double.parseDouble(matcher.group(2)));	
			}
			
			if (matcher.group(matcher.groupCount()) == "f") {
				gender = Gender.FEMALE;
			} else {
				gender = Gender.MALE;
			}
		this.addClient(new Client(account,matcher.group(4),gender));
		}
	}
	
	public Client getClientById(int id) throws ClientNotExistException {
		if(id >= 0) {
			if(clients.size() > id) {
				return clients.get(id);
			} else {
				throw new ClientNotExistException("Client do not exist!");
			}	
		} else {
			throw new IllegalArgumentException("id incorrect");
		}
	}
	
	public int getClientCount() {
		return this.clients.size();
	}
	
}
